<script setup lang="ts">
import { ref, watch } from 'vue'
import type { FormInstance, FormRules } from 'element-plus'
import { cloneDeep, isEqual } from "lodash-es"
import { addMenu, updateMenu, getTreeselectNoBtn, getMenu } from '@/common/apis/system/menu'
const props = defineProps<{
  dialogShow: boolean
  menuId: string
  menuDisabled: boolean
  topMenu?: string
  topType?: string
}>()
// 弹窗
const dialogVisible = ref(false)
const isEdit = ref(false)
const isLoading = ref(false)
// 发送事件
const emit = defineEmits(['update:dialogShow', 'handleSave'])
// 表单
const formData = ref({
  parentId: '', // 上级菜单id
  parentName: '', // 上级菜单
  menuName: '', // 菜单名称
  path: '', // 菜单地址
  component: '', // 组件路径
  routeName: '', // 路由名称
  perms: '', // 权限字符串
  icon: '', // 图标
  orderNum: 1, // 排序
  isFrame: 0, // 打开方式
  menuType: 'M', // 菜单类型
  visible: 0, // 显示状态
  status: 0, // 菜单状态
  isCache: 0, // 是否缓存
  singleRoute: 0, // 是否为独立路由
  cacheKey: '', // 页面缓存关键字
  activeMenu: '' // 激活菜单
})
// 上级菜单
const topMenuText = ref('')
// 树形结构
const treeRef = ref()
// 表单
const ruleFormRef = ref<FormInstance>()
// 是否详情
const isDetail = ref(false)
// 文本
const textMap = ref('新增菜单')
const defaultFormData = ref({
  parentName: '', // 上级菜单
  parentId: '', // 上级菜单id
  menuName: '', // 菜单名称
  path: '', // 菜单地址
  component: '', // 组件路径
  routeName: '', // 路由名称
  perms: '', // 权限字符串
  icon: '', // 图标
  orderNum: 1, // 排序
  isFrame: 0, // 打开方式
  menuType: 'M', // 菜单类型
  visible: 0, // 显示状态
  status: 0, // 菜单状态
  isCache: 0, // 是否缓存
  singleRoute: 0, // 是否为独立路由
  cacheKey: '', // 页面缓存关键字
  activeMenu: '' // 激活菜单
})
// 图标列表
interface IconList {
  name: string
  value: string
}
const parentNameOptions = ref([])
// 树形结构
const treeSelectRef = ref()
// 表单规则
const rules = ref<FormRules>({
  menuName: [{ required: true, message: '请输入菜单名称', trigger: 'blur' }],
  path: [{ required: true, message: '请输入菜单地址', trigger: 'blur' }],
  component: [{ required: true, message: '请输入组件路径', trigger: 'blur' }],
  routeName: [{ required: true, message: '请输入路由名称', trigger: 'blur' }],
  perms: [{ required: true, message: '请输入权限字符串', trigger: 'blur' }],
  orderNum: [{ required: true, message: '请输入排序', trigger: 'blur' }],
  cacheKey: [{ required: true, message: '请输入页面缓存关键字', trigger: 'blur' }],
  activeMenu: [{ required: true, message: '请输入激活菜单', trigger: 'blur' }],
})
// 保存
const handleSubmit = (formEl: FormInstance | undefined) => {
  if (!formEl) return
  formEl.validate((valid, fields) => {
    if (valid) {
      if (props.menuId !== '') {
        const upDateFrom = { ...formData.value, menuId: props.menuId }
        updateMenu(upDateFrom).then(res => {
          handleCancel()
        })
      } else {
        addMenu(formData.value).then(res => {
          handleCancel()
        })
      }


    }
  })
}
// 取消
const handleCancel = () => {
  emit('update:dialogShow', false)
  formData.value = {
    parentName: '',
    parentId: '',
    menuName: '',
    path: '',
    component: '',
    routeName: '',
    perms: '',
    icon: '',
    orderNum: 1,
    isFrame: 0,
    menuType: 'M',
    visible: 0,
    status: 0,
    isCache: 0,
    singleRoute: 0,
    cacheKey: '',
    activeMenu: ''
  }
  isDetail.value = false
}
// 设置节点选中
const setNodeChecked = (node: any, checked: boolean) => {
  treeRef.value.store.nodesMap[node.$treeNodeId].checked = checked;
  if (node.children && node.children.length > 0) {
    node.children.forEach((child: any) => {
      setNodeChecked(child, checked);
    });
  }
}
// 获取不包含按钮下拉树列表
const getTreeselect = () => {
  getTreeselectNoBtn().then((res: any) => {
    parentNameOptions.value = res.data
  })
}
// 编辑
const handleEdit = () => {
  defaultFormData.value = cloneDeep(formData.value)
  isEdit.value = true
}
function handleCloseTip(done: () => void) {
  if (isDetail.value) {
    // 校验值是否相同
    if (isEqual(defaultFormData.value, formData.value)) {
      handleCancel()
      done()
      return
    }
    ElMessageBox.confirm("当前编辑未保存，是否确定关闭？").then(() => {
      done()
    })
    return
  } else {
    handleCancel()
    done()
  }
}
const menuType = ref('M')
// 选择上级菜单
const handleSelectParent = () => {
  if (treeSelectRef.value) {
    const node = treeSelectRef.value.getCheckedNodes();
    formData.value.parentId = node[0].id
    if (node[0].menuType === 'C') {
      menuType.value = 'C'
      formData.value.menuType = 'C'
    } else {
      menuType.value = 'M'
      formData.value.menuType = 'M'
    }
  }
}
const sreach = () => {
  getMenu(props.menuId).then((res: any) => {
    topMenuText.value = res.data.parentName
    formData.value = res.data
  })
}
// 监听弹窗
watch(() => props.dialogShow, (newVal) => {
  dialogVisible.value = newVal
  getTreeselect()
  if (props.menuId) {
    textMap.value = '菜单详情'
    isDetail.value = false

  } else {
    textMap.value = '新增菜单'
    topMenuText.value = props.topMenu ? JSON.parse(JSON.stringify(props.topMenu)) : ''
    if (props.topMenu) {
      formData.value.parentName = props.topMenu
    } else {
      formData.value.parentName = ''
    }
    defaultFormData.value = cloneDeep(formData.value)
    isDetail.value = true
  }
})
// 监听上级菜单选择的是否为菜单
watch(() => props.topType, (newVal) => {
  if (newVal) {
    if (props.topType !== 'C') {
      formData.value.menuType = 'M'
      menuType.value = 'M'
    } else {
      formData.value.menuType = 'C'
      menuType.value = 'C'
    }
  }
})
const handleEditCancel = () => {
  sreach()
  isEdit.value = false;
}
</script>
<template>
  <div>
    <el-drawer v-model="dialogVisible" size="700" :show-close="false" :before-close="handleCloseTip"
      @close-auto-focus="handleCancel" @close="handleCancel">
      <template #header>
        <h4>{{ textMap }}</h4>
        <el-space justify="end">
          <!-- 详情页面 -->
          <template v-if="!isDetail">
            <!-- 编辑状态：显示取消保存和保存按钮 -->
            <el-button v-if="isEdit" @click="handleEditCancel">
              取消保存
            </el-button>
            <el-button v-if="isEdit" type="primary" :loading="isLoading" v-throttle="() => handleSubmit(ruleFormRef)">
              保存
            </el-button>
            <!-- 非编辑状态：显示编辑按钮 -->
            <el-button v-if="!isEdit" type="primary" @click="handleEdit">
              编辑
            </el-button>
          </template>

          <!-- 上传页面：只显示保存按钮 -->
          <template v-else>
            <el-button type="primary" :loading="isLoading" v-throttle="() => handleSubmit(ruleFormRef)">
              保存
            </el-button>
          </template>
        </el-space>
      </template>
      <div class="drawer-content" v-if="isDetail">
        <el-form :model="formData" label-width="140px" :rules="rules" ref="ruleFormRef">
          <el-form-item label="上级菜单" prop="parentId">
            <el-tree-select @change="handleSelectParent" ref="treeSelectRef" v-model="formData.parentId" node-key="id"
              :data="parentNameOptions" check-strictly :render-after-expand="false" show-checkbox />
          </el-form-item>
          <el-form-item label="类型" prop="menuType">
            <el-radio-group v-model="formData.menuType">
              <el-radio value="M" v-if="menuType === 'M'">目录</el-radio>
              <el-radio value="C">菜单</el-radio>
              <el-radio value="F" v-if="menuType !== 'M'">按钮</el-radio>
            </el-radio-group>
          </el-form-item>
          <el-form-item :label="formData.menuType === 'F' ? '按钮名称' : formData.menuType === 'C' ? '菜单名称' : '目录名称'"
            prop="menuName">
            <el-input v-model="formData.menuName"
              :placeholder="formData.menuType === 'F' ? '请输入按钮名称' : formData.menuType === 'C' ? '请输入菜单名称' : '请输入目录名称'" />
          </el-form-item>
          <el-form-item :label="formData.menuType === 'C' ? '菜单地址' : '目录地址'" v-if="formData.menuType !== 'F'"
            prop="path">
            <el-input v-model="formData.path" :placeholder="formData.menuType === 'C' ? '请输入菜单地址' : '请输入目录地址'" />
          </el-form-item>
          <el-form-item label="组件路径" v-if="formData.menuType === 'C'" prop="component">
            <el-input v-model="formData.component" placeholder="请输入组件路径" />
          </el-form-item>
          <el-form-item label="路由名称" v-if="formData.menuType !== 'F'" prop="routeName">
            <el-input v-model="formData.routeName" placeholder="请输入路由名称" />
          </el-form-item>
          <el-form-item label="页面缓存关键字" v-if="formData.menuType === 'C'" prop="cacheKey">
            <el-input v-model="formData.cacheKey" placeholder="请输入页面缓存关键字" />
          </el-form-item>
          <el-form-item label="激活菜单" v-if="formData.menuType === 'C'" prop="activeMenu">
            <el-input v-model="formData.activeMenu" placeholder="请输入激活菜单关键字" />
          </el-form-item>
          <el-form-item label="权限字符串" v-if="formData.menuType === 'C' || formData.menuType === 'F'" prop="perms">
            <el-input v-model="formData.perms" placeholder="请输入权限字符串" />
          </el-form-item>
          <el-form-item label="排序" prop="orderNum">
            <el-input-number v-model.number="formData.orderNum" :min="1" :step="1" clearable step-strictly
              :controls="false" />
          </el-form-item>
          <el-form-item label="图标" v-if="formData.menuType !== 'F'" prop="icon">
            <el-input v-model="formData.icon" placeholder="请输入图标名称" />
          </el-form-item>
          <el-form-item label="是否外链" v-if="formData.menuType !== 'F'" prop="isFrame">
            <el-radio-group v-model="formData.isFrame">
              <el-radio :value="0">是</el-radio>
              <el-radio :value="1">否</el-radio>
            </el-radio-group>
          </el-form-item>
          <el-form-item label="是否为独立路由" v-if="formData.isFrame === 1">
            <el-radio-group v-model="formData.singleRoute">
              <el-radio :value="0">是</el-radio>
              <el-radio :value="1">否</el-radio>
            </el-radio-group>
          </el-form-item>
          <el-form-item label="显示状态" v-if="formData.menuType !== 'F'" prop="visible">
            <el-radio-group v-model="formData.visible">
              <el-radio :value="0">显示</el-radio>
              <el-radio :value="1">隐藏</el-radio>
            </el-radio-group>
          </el-form-item>
          <el-form-item :label="formData.menuType === 'M' ? '目录状态' : formData.menuType === 'C' ? '菜单状态' : '按钮状态'"
            prop="status">
            <el-radio-group v-model="formData.status">
              <el-radio :value="0">正常</el-radio>
              <el-radio :value="1">停用</el-radio>
            </el-radio-group>
          </el-form-item>
          <el-form-item label="是否缓存" v-if="formData.menuType === 'C'" prop="isCache">
            <el-radio-group v-model="formData.isCache">
              <el-radio :value="0">是</el-radio>
              <el-radio :value="1">否</el-radio>
            </el-radio-group>
          </el-form-item>
        </el-form>
      </div>
      <div v-else>
        <el-form width="600" label-width="140px" label-position="right" :close-on-click-modal="false"
          class="custom-view-form">
          <el-form-item label="上级菜单:">
            {{ $getViewText(topMenuText) }}
          </el-form-item>
          <el-form-item label="类型：">
            {{ $getViewText(formData.menuType === 'M' ? '目录' : formData.menuType === 'C' ? '菜单' : '按钮') }}
          </el-form-item>
          <el-form-item :label="formData.menuType === 'F' ? '按钮名称' : formData.menuType === 'C' ? '菜单名称' : '目录名称'">
            {{ $getViewText(formData.menuName) }}
          </el-form-item>
          <el-form-item :label="formData.menuType === 'C' ? '菜单地址' : '目录地址'">
            {{ $getViewText(formData.path) }}
          </el-form-item>
          <el-form-item v-if="formData.menuType === 'C'" label="组件路径：">
            {{ $getViewText(formData.component) }}
          </el-form-item>
          <el-form-item v-if="formData.menuType !== 'F'" label="路由名称：">
            {{ $getViewText(formData.routeName) }}
          </el-form-item>
          <el-form-item v-if="formData.menuType === 'C'" label="页面缓存关键字：">
            {{ $getViewText(formData.cacheKey) }}
          </el-form-item>
          <el-form-item v-if="formData.menuType === 'C'" label="激活菜单：">
            {{ $getViewText(formData.activeMenu) }}
          </el-form-item>
          <el-form-item v-if="formData.menuType === 'C' || formData.menuType === 'F'" label="权限字符串：">
            {{ $getViewText(formData.perms) }}
          </el-form-item>
          <el-form-item v-if="formData.menuType !== 'F'" label="图标：">
            {{ $getViewText(formData.icon) }}
          </el-form-item>
          <el-form-item v-if="formData.menuType !== 'F'" label="排序：">
            {{ $getViewText(formData.orderNum) }}
          </el-form-item>
          <el-form-item v-if="formData.menuType !== 'F'" label="打开方式：">
            {{ $getViewText(formData.isFrame === 0 ? '内链' : '外链') }}
          </el-form-item>
          <el-form-item v-if="formData.isFrame === 1" label="是否为独立路由：">
            {{ $getViewText(formData.singleRoute === 0 ? '是' : '否') }}
          </el-form-item>
          <el-form-item v-if="formData.menuType !== 'F'" label="显示状态：">
            {{ $getViewText(formData.visible === 0 ? '显示' : '隐藏') }}
          </el-form-item>
          <el-form-item v-if="formData.menuType !== 'F'"
            :label="formData.menuType === 'M' ? '目录状态' : formData.menuType === 'C' ? '菜单状态' : '按钮状态'">
            {{ $getViewText(formData.status === 0 ? '正常' : '停用') }}
          </el-form-item>
          <el-form-item v-if="formData.menuType === 'C'" label="是否缓存：">
            {{ $getViewText(formData.isCache === 0 ? '是' : '否') }}
          </el-form-item>
        </el-form>
      </div>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="handleCancel">退 出</el-button>
        </div>
      </template>
    </el-drawer>
  </div>
</template>

<style lang="scss" scoped></style>
